const BASEMAP_INTERNATIONAL_STANDARD = [
  '',
  '',
  'abc',
  'def',
  'ghi',
  'jkl',
  'mno',
  'pqrs',
  'tuv',
  'wxyz',
];

const SegmentState = {
  INITIAL: 0,
  BREAK: 1,
  WORD: 2,
};

const breakdown = function(phoneNumber, map) {
  const result = [];
  let segment = '';
  let segmentState = SegmentState.INITIAL;
  for (let i = 0; i < phoneNumber.length; i++) {
    if (map[phoneNumber.charAt(i)] === '') {
      if (segmentState === SegmentState.INITIAL) {
        segment = phoneNumber.charAt(i);
      } else if (segmentState === SegmentState.BREAK) {
        segment += phoneNumber.charAt(i);
      } else {
        result.push(segment);
        segment = phoneNumber.charAt(i);
      }
      segmentState = SegmentState.BREAK;
    } else {
      if (segmentState === SegmentState.INITIAL) {
        segment = phoneNumber.charAt(i);
      } else if (segmentState === SegmentState.BREAK) {
        result.push(segment);
        segment = phoneNumber.charAt(i);
      } else {
        segment += phoneNumber.charAt(i);
      }
      segmentState = SegmentState.WORD;
    }
  }
  result.push(segment);
  return result;
};

const getAllWordCombo = function(phoneNumber, map) {
  const result = [];
  const step = (i, phoneNumber, map, result, word) => {
    if (i === phoneNumber.length) {
      result.push(word);
      return;
    }
    for (let j = 0; j < map[phoneNumber.charAt(i)].length; j++) {
      step(i + 1, phoneNumber, map, result, word + map[phoneNumber.charAt(i)].charAt(j));
    }
  };
  step(0, phoneNumber, map, result, '');
  return result;
};

const singleRun = (phoneNumber, map) => {
  const b = breakdown(phoneNumber, map);
  for (const i in b) {
    if (map[b[i].charAt(0)] === '') {
      continue;
    }
    const combo = getAllWordCombo(b[i], map);
    retrieveAllWords(() => {
      for (const j in combo) {
        const hit = words.split('\n').filter(word => word.toLowerCase() === combo[j]);
        if (hit.length > 0) {
          console.log(b[i], combo[j], hit);
        }
      }
    });
  }
};

let words;
const retrieveAllWords = callback => {
  if (words) {
    callback();
    return;
  }
  const fs = require('fs');
  fs.readFile('words', 'utf-8', (err, files) => {
    words = files;
    callback();
  });
};
retrieveAllWords(()=>{});

singleRun('15810055307', BASEMAP_INTERNATIONAL_STANDARD);
singleRun('13811748749', BASEMAP_INTERNATIONAL_STANDARD);
singleRun('2830557041', BASEMAP_INTERNATIONAL_STANDARD);
